package api;

import java.util.LinkedList;
import java.util.List;

import api.error.InvalidRequestException;
import api.error.UnknownResponseException;

public class MicrobotInterpreter extends Interpreter{

	public Command[] possibleCommands = new Command[]{
			new Command("step", new String[]{"speed", "BASE", "SHOULDER", "ELBOW", "PITCH", "ROLL", "GRIP"}, "Moves the robot's joints to new positions at the given speed. The joint values describe the change from their current position. Ex: +/- 2000"),
			new Command("close", new String[]{"speed"}, "Close the gripper at the given speed"),
			new Command("set", new String[]{"speed"}, "Set the units speed for Teach Control"),
			new Command("reset", new String[]{}, "Resets each motor, essentially clearing all configuration data."), 
			new Command("read", new String[]{}, "Reads the robots internal register values."),
			new Command("delay", new String[]{"count"}, "Set the delay in 1/2 milliseconds that the robot takes when sending data back to the pc")};
	
	public Command[] getCommands(){return possibleCommands;}
	public String[] getStartupCommands(){return new String[]{"reset"};}
	public String[] getReleaseCommands(){return new String[0];}
	/**
	 * Looking for one of:
	 * step(int speed, int j1HalfSteps, ..., int j6HalfSteps)
	 * - speed 0 to 245
	 * - j*HalfSteps - number of halfsteps that joint should move +/-
	 */
	public List<String> interpretRequest(String command) throws InvalidRequestException{
		if(command == null || command.length() == 0)
			throw new InvalidRequestException(command, "No command given");
		
		String[] commander = command.split("[ (]");
		String name = commander[0];
		Command it = getCommand(name);
		
		if(it == null)
			throw new InvalidRequestException(command, "Unknown Command Given: " + name);
		
		String resultCommand = "@" + name.toUpperCase() + " ";
		if(it.getParams().length > 0)
		{
			int start = command.indexOf("(");
			int end = command.indexOf(")");
			if(start < 0)
				throw new InvalidRequestException(command, "Missing '(' in parameter list");
			if(end < 0)
				throw new InvalidRequestException(command, "Missing ')' in parameter list");
			
			String paramSt = command.substring(start+1, end);
			String[] params = paramSt.split(",");
			int deductions = 0;//for empty params
			for(String s : params)
			{
				if(s.trim().length() == 0)
					deductions ++;
			}
			if((params.length-deductions) != it.getParams().length)
				throw new InvalidRequestException(command, "Incorrect number of parameters. Given " + (params.length-deductions) + ", expected " + it.getParams().length);
			
			for(String s : params)
				resultCommand += s + ",";
			
			resultCommand = resultCommand.substring(0, resultCommand.length()-1);
		}
		else
		{
			int start = command.indexOf("(");
			int end = command.indexOf(")");
			if((start > 0 && end < 0) || (end > 0 && start < 0) || (start > end))
				throw new InvalidRequestException(command, "Invalid parameter list");
			
			if(end > start + 1)
			{
				String paramSt = command.substring(start + 1, end).trim();
				if(paramSt.length() > 0)
					throw new InvalidRequestException(command, "No parameters should be given");
			}
		}
		resultCommand += "\r";
		System.out.println(resultCommand);
		List<String> l = new LinkedList<String>();
		l.add(resultCommand);
		return l;
	}
	

	public List<String> interpretResponse(String response){
		
		List<String> ret = new LinkedList<String>();
		response = response.replaceAll("\r","");
		
		int i = 3;
		try{
			i = Integer.parseInt(response.trim());
		}catch(Exception e){}
		
		if(i == 0)
			ret.add("Execution Error");
		else if(i == 1)
			ret.add("Execution OK");
		else if(i == 2)
			ret.add("Operation Stopped");
		else
			ret.add(response);
		
		
		return ret;
	}
	
	public String toString()
	{
		return "Microbot";
	}
	@Override
	public boolean isResponseGood(String response) {
		response = response.replaceAll("\r","");
		
		int i = 0;
		try{
			i = Integer.parseInt(response.trim());
		}catch(Exception e){
			return true;//read() response
		}
		
		if(i != 1)
			return false;

		return true;
	}

}
